home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / MUBBS_MO / MODEMS_M / MODEMS_M.C < prev   
Text File  |  1991-11-21  |  9KB  |  300 lines

  1. /*
  2.  *  Modems Module.c
  3.  *
  4.  *    This program source code and it's compiled version is
  5.  *  Copyright (c) 1991 N. Hawthorn.
  6.  *  This program source code and it's compiled version IS NOT IN THE
  7.  *  PUBLIC DOMAIN ! Please read the "COPYRIGHT NOTICE / NH" file for details
  8.  *  regarding use of this program source code and it's compiled version.
  9.  *
  10.  *  This module's name is "modems", it's type is "MOD1",  use a resource mover
  11.  *  to assign a new number to it, that's why we name our modules !
  12.  *
  13.  *  I don't recomend sysops using "no carrier detect". A cable SHOULD be made.
  14.  *  However, this module handles even the lame mode. MUBBS will probably hang
  15.  *  most of the time, and MUBBS will look real stupid for this, but the code
  16.  *  is in. It just tries to hang up in every baud rate ! This is totally LAME !
  17.  *
  18.  *
  19.  *  This is where it all starts...
  20.  *
  21.  */
  22.  
  23. #define INMAIN
  24.  
  25. #include     <SetUpA4.h>
  26. #include    "MUBBS Module.h"
  27.  
  28. extern Ptr SCCRd : 0x1D8;
  29. extern Ptr SCCWr : 0x1DC;
  30.  
  31. /* my globals for this module */
  32.  
  33. int usercarr[maxport]; /* if TRUE then detect carrier, if not use LAME time out method*/
  34. char maxbaud[maxport][10]; /* the max baudrate for this modem */
  35.  
  36. struct SSS{
  37.         char string[64]; /* this is a struct to pass some variables to the modems module */
  38.         int mode;   /* the mode to use */
  39.         }; 
  40.  
  41.  
  42. pascal void main (mode1,G1,P1)
  43.        int mode1;
  44.        struct GS *G1;
  45.        Ptr P1;
  46. {
  47. Handle temph;
  48. float version = 0.5; /* what version of MUBBS you are compatable with IE: .5 and above */
  49. RememberA0(); SetUpA4(); /* This sets up the A4 register to access our globals */
  50. asm { _RecoverHandle }; asm {move.l a0,temph}; HLock(temph); /* locks our module, do this ! */
  51.  
  52. G=G1; /* This MUST be the first thing you do in main only, it sets up the struct globals */
  53. mode[u]=mode1; /* set up our mode so that you can read it anywhere */
  54.  
  55. switch (mode[u]) { /* any un-handled modes return error from this module */
  56.  
  57.     case 3:
  58.         modem(P1); /* we need our globals, so we LOCK and stay that way */
  59.         G->moduleresult=0;
  60.         goto skip1;        /* DON'T UNLOCK */
  61.         break;
  62.     case 98: /* NOTE that this DOESN'T unlock */
  63.         versionck(version); /* just return after this call, don't modify anything */
  64.         goto skip1;        /* DON'T UNLOCK */
  65.         break;        
  66.     case 0:
  67.         strcpy (G->programmer,"N Hawthorn"); /* show the programmer's name up to 20 chars*/
  68.         setupall(); /* set up the modem globals */
  69.         G->moduleresult=99; /* we put 99 here because we need to be called to CLOSE */
  70.         goto skip1;        /* DON'T UNLOCK */
  71.         break;
  72.     case 1:
  73.         G->moduleresult=0; /* bye bye call, UNLOCK NOW */
  74.         break;
  75.     default:
  76.         G->moduleresult=1; /* return bad code */
  77.     };
  78.  
  79. HUnlock(temph); /* unlocks this module, do this ! */
  80.  
  81. skip1:
  82. RestoreA4(); /* call this when you are all done */
  83. }
  84.  
  85.  
  86. modem(S)
  87. struct SSS *S;
  88. {
  89.  
  90. switch (S->mode){
  91.     case 0:
  92.         connect(S);
  93.         break;
  94.     case 1:
  95.         reset(S);
  96.         break;
  97.     case 2:
  98.         hangup(S);
  99.         break;
  100.     }
  101. }
  102.  
  103. connect(S)
  104. struct SSS *S;
  105. { /* mode = 0 for a CONNECT condition, ATA was already sent, figure out what baud */
  106.  
  107. while (TRUE){
  108.     if (strcmp(S->string,"13\x0D") == 0) { /* result code */
  109.         strcpy(G->userbaud[u],"19200"); /* set the baud rate to 19200 */
  110.         break; /* YOU BETTER HAVE HARDWARE HANDSHAKING FOR THIS BAUD RATE ! */
  111.         }
  112.     if (strcmp(S->string,"12\x0D") == 0) { /* result code */
  113.         strcpy(G->userbaud[u],"9600"); /* set the baud rate to 9600 */
  114.         break;
  115.         }
  116.     if (strcmp(S->string,"10\x0D") == 0) { /* result code */
  117.         strcpy(G->userbaud[u],"2400"); /* set the baud rate to 2400 */
  118.         break;
  119.         }
  120.     if (strcmp(S->string,"5\x0D") == 0) {
  121.         strcpy(G->userbaud[u],"1200"); /* set the baud rate to 1200 */
  122.         break;
  123.         }
  124.     if (strcmp(S->string,"1\x0D") == 0) {
  125.         strcpy(G->userbaud[u],"300"); /* set the baud rate to 300 */
  126.         break;
  127.         }
  128.     S->mode=FALSE; /* show we have a bad baud rate, hang up */
  129.     return;
  130.     }
  131. G->carrdet[u]=usercarr[u]; /* set it up so we detect carrier loss now that we're connected*/
  132. S->mode=TRUE; /* show its OK */
  133.  
  134. /* MUBBS main handles the rest from here, thanks for your help ! */
  135.  
  136. }
  137.  
  138.  
  139. reset(S)
  140. struct SSS *S;
  141. { /* mode = 1 for a modem reset call, send the set up string */
  142. char modemstring[256];
  143.  
  144. setstuff(modemstring,u); /* get the strings for this line */
  145. G->serclose();
  146. G->seropen();
  147. print("C> Modem OK if you see \"0\" below (4 is error). Port now set to %s baud\n",G->userbaud[u]);
  148. sendnc("AT\r"); /* get it to see the new baud rate */
  149. wait(1);
  150. showstat();
  151. sendnc("AT\r"); /* get it to see the new baud rate */
  152. wait(1);
  153. showstat(); /* feedback for the sysop */
  154.  
  155. sendnc(modemstring); /* NO CHECK OUTPUT DOES NOT CHECK FOR ANYTHING !! */
  156. wait(2);                    /* EVEN ONLINE FLAGS */
  157. showstat(); /* feedback for the sysop */
  158. sendnc(modemstring); /* send the string twice to make sure */
  159. wait(2);
  160. showstat();
  161. G->serflush(); /* dump any garbage characters */
  162. }
  163.  
  164.  
  165. hangup(S)
  166. struct SSS *S;
  167. {/* mode = 2 for a modem hangup call, try to hang up modem */
  168. int
  169.     temp1 = 0,
  170.     temp2,
  171.     temp3 = 0,
  172.     baud,
  173.     flag = 1;
  174.  
  175. Byte check;
  176. char modemstring[256], savebaud[maxnamelength];
  177.  
  178. strcpy(savebaud,G->userbaud[u]); /* save the current baud rate */
  179. setstuff(modemstring,u); /* get the strings for this line */
  180.  
  181. if (strcmp(maxbaud[u],"300") == 0) baud=5; /* find the max baud */
  182. else if (strcmp(maxbaud[u],"1200") == 0) baud=4; /* this sets it to this after first try */
  183. else if (strcmp(maxbaud[u],"2400") == 0) baud=3;
  184. else if (strcmp(maxbaud[u],"9600") == 0) baud=2;
  185. else if (strcmp(maxbaud[u],"19200") == 0) baud=1;
  186.  
  187. temp2=baud;
  188. strcpy(G->userbaud[u],savebaud); /* recover the current baud rate */
  189.  
  190. while (TRUE) {
  191.     while (temp1++ < 8) {
  192.         if (G->forgetusers && !G->local[u]) return; /* if we are not logged in locally and cancel all users */
  193.         if (usercarr[u]) {
  194.             if (u == 0) {if ((check = *(SCCRd + 2) & 0x20)) return; }/* CTS is bit 5, 1= carr loss */
  195.             if (u == 1) {if ((check = *(SCCRd + 0) & 0x20)) return; }/* CTS is bit 5, 1= carr loss */
  196.             print("C>      CARRIER STILL PRESENT ON LINE %d, HANGING UP !!\n",(u+1));
  197.             }
  198.         else sendnc("Hardware carrier detect cable not installed.]Please hang up now.]"); /* try the good old standard */
  199.         temp3++; /* try at current baud rate first, then goto highest next */
  200.         print("C> Hanging up at %s baud, attempt=%d\n",G->userbaud[u],temp3);
  201.         G->serclose();
  202.         G->seropen();
  203.         wait(2);
  204.         if (flag) {sendnc("\x02\x02\x02");} /* send the ecape code and delay 2 seconds */
  205.         else sendnc("+++"); /* try the good old standard */
  206.         wait(2);
  207.         if (!usercarr[u]) { /* for LAME mode */
  208.             sendnc(modemstring); /* send the reset string, try to hang up now */
  209.             wait(2);
  210.             sendnc("+++"); /* try the good old standard just incase */
  211.             wait(2);
  212.             sendnc("\r"); /* send a return to clear things */
  213.             wait(1);
  214.             }
  215.         showstat(); /* prints any input to the screen */
  216.         sendnc(modemstring); /* send the reset string */
  217.         wait(1);
  218.         showstat(); /* feedback for the sysop */
  219.         lll:
  220.         if (temp2 == 1) strcpy(G->userbaud[u],"19200"); /* set the baud rate to 19200 */
  221.         if (temp2 == 2) strcpy(G->userbaud[u],"9600"); /* set the baud rate to 9600 */
  222.         if (temp2 == 3) strcpy(G->userbaud[u],"2400"); /* set the baud rate to 2400 */
  223.         if (temp2 == 4) strcpy(G->userbaud[u],"1200"); /* set the baud rate to 1200 */
  224.         if (temp2 == 5) strcpy(G->userbaud[u],"300"); /* set the baud rate to 300 */
  225.         if (temp2 >= 6 && !usercarr[u]) return; /* if no carrier detect, we tried all assume hung up */
  226.         if (temp2++ >= 6) {
  227.             temp2=baud; /* set it back to the max baud and do it again */
  228.             goto lll;
  229.             }
  230.         }
  231.     flag = ! flag;
  232.     temp1 = 0;
  233.     if (temp3 >= 80) {
  234.         print("\nC>     ERROR !! Tried 80 times to reset modem, FORGET LINE %d !!\n",(u+1));
  235.         loop:
  236.         otheruser(TRUE); /* we just sit here and do nothing */
  237.         goto loop;
  238.         }
  239.     }
  240. }
  241.  
  242. showstat() /* shows any input from the modem */
  243. {
  244. G->carrdet[u]=FALSE;
  245. while (G->serin()){ /* serin doesn't check for carrier here ! */
  246.     if (G->input[u] == 0x0A) continue;
  247.     print("%c",G->input[u]);
  248.     }
  249. }
  250.  
  251. setupall(){ /* called up once at start to set up the modem globals */
  252. char modemstring[256];
  253. int user;
  254.  
  255. user=0; /* note that this is not messing with "u" */
  256. do { /* sets the modem globals for each user */
  257.     setstuff(modemstring,user); /* get the strings for this line */
  258.     } while (++user < G->users); /* user = 0 to maxport (counting here starts at 0) */
  259. }
  260.  
  261. setstuff(modemstring,user)
  262. char *modemstring;
  263. int user;
  264. { /* set up strings */
  265. char tempB[11],tempCD[11],tempDTR[11];
  266. int x;
  267. FILE *stream;
  268.  
  269. strcpy(modemstring,"ATH0E0V0M1S0=0S2=2\r"); /* standard modem string, just incase */
  270. strcpy(tempB,"2400"); /* standard 2400, just incase */
  271. strcpy(tempCD,"1"); /* Carrier detect, just incase */
  272. strcpy(tempDTR,"0"); /* No DTR, just incase */
  273.  
  274. if ((stream = fopen(":bbssupport:modems", "r")) == NULL) {
  275.     print("C> FILE ERROR - cannot open :bbssupport:modems\n");
  276.     print("C> SENDING A STANDARD STRING TO THE MODEM !!\n ");
  277.     goto skip;
  278.     }
  279.  
  280.  
  281. for(x=0; x<=user; x++){ /* get this line's modem string */
  282.     if (fscanf(stream,"%10[^,],%10[^,],%10[^\n]\n%255[^\n]\n",tempB,tempCD,tempDTR,modemstring) == EOF) break; /* get the string */
  283.     }
  284.  
  285. fclose(stream);
  286. strcat(modemstring,"\r");
  287.  
  288. skip:
  289. strcpy(G->userbaud[user],tempB); /* set to the MAX baud rate */
  290. strcpy(maxbaud[user],tempB); /* set to the MAX baud rate */
  291. usercarr[user]= strtoint(tempCD); /* see if we are to detect carrier or if it's LAME BBS time */
  292. if(usercarr[user] == 0) usercarr[user]=FALSE;
  293. else usercarr[user]=TRUE;
  294.  
  295. G->usedtr[user]= strtoint(tempDTR); /* Use DTR hang up? Not used here yet, but it's set anyway */
  296. if(G->usedtr[user] == 0) G->usedtr[user]=FALSE;
  297. else G->usedtr[user]=TRUE;
  298. }
  299.  
  300.